package org.example.domain.strategy.service.rule.filter.factory;

import com.alibaba.fastjson2.util.AnnotationUtils;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.example.domain.strategy.model.entity.RuleActionEntity;
import org.example.domain.strategy.service.annotation.LoginStrategy;
import org.example.domain.strategy.service.rule.filter.ILogicFilter;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 规则工厂
 */
@Service
public class DefaultLogicFactory {

    public Map<String, ILogicFilter<?>> logicFilterMap = new ConcurrentHashMap<>();

    //Spring 会自动扫描项目中所有 “实现了ILogicFilter接口的类”（比如RuleBackListLogicFilter、RuleWeightLogicFilter）
    // 创建它们的实例，然后打包成一个List注入到这个构造方法中。
    public DefaultLogicFactory(List<ILogicFilter<?>> logicFilters) {
        //遍历每个过滤器，每个过滤器类上都会加@LoginStrategy注解，用来标记 “这个过滤器对应哪个规则类型”
        //从注解中拿到logicModel（规则类型枚举，如DefaultLogicFactory.LogicModel.RULE_BLACKLIST）
        //再从枚举中拿到 “规则类型唯一标识”（比如rule_blacklist）
        // 用其“规则类型唯一标识”作为键，过滤器实例作为值，存入logicFilterMap。“规则标识→过滤器实例”
        logicFilters.forEach(logic -> {
            LoginStrategy strategy = AnnotationUtils.findAnnotation(logic.getClass(), LoginStrategy.class);
            if (null != strategy) {
                logicFilterMap.put(strategy.logicModel().getCode(), logic);
            }
        });
       // logicFilterMap里会有类似 {"rule_blacklist": 黑名单过滤器实例, "rule_weight": 权重过滤器实例}
    }

    /**
     * 对外提供logicFilterMap的访问入口
     * @return
     * @param <T>
     */
    public <T extends RuleActionEntity.RaffleEntity> Map<String, ILogicFilter<T>> openLogicFilter() {
        return (Map<String, ILogicFilter<T>>) (Map<?, ?>) logicFilterMap;
    }

    @Getter
    @AllArgsConstructor
    public enum LogicModel {

        RULE_WIGHT("rule_weight","【抽奖前规则】根据抽奖权重返回可抽奖范围KEY","before"),
        RULE_BLACKLIST("rule_blacklist","【抽奖前规则】黑名单规则过滤，命中黑名单则直接返回","before"),
        RULE_LOCK("rule_lock","【抽奖中规则】解锁奖品规则过滤，抽取n次后可解锁相应奖品" ,"center"),
        RULE_LUCK_AWARD("rule_luck_award","【抽奖后规则】幸运奖兜底","after")

        ;

        private final String code;
        private final String info;
        private final String type;

        public static boolean isCenter(String code){
            return "center".equals(LogicModel.valueOf(code.toUpperCase()).type);
        }

        public static boolean isAfter(String code){
            return "after".equals(LogicModel.valueOf(code.toUpperCase()).type);
        }
    }

}